package service;

import com.distribute.pojo.PageInfo;
import com.distribute.pojo.Result;
import com.distribute.pojo.enums.ServiceType;
import com.distribute.pojo.project.Project;
import com.distribute.utils.JsonUtils;
import com.fasterxml.jackson.core.type.TypeReference;
import constant.DSConstants;
import constant.MediaTypeConstants;
import core.api.ApiClient;
import exception.ApiException;
import service.api.ProjectService;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class DSProjectService implements ProjectService {

    private final ApiClient apiClient;

    public DSProjectService(ApiClient apiClient) {
        this.apiClient = apiClient;
    }

    @Override
    public Project createProject(String projectName, String desc) {
        if (projectName == null) {
            throw new ApiException("project name is null");
        }
        Project project = this.getProject(projectName);
        if(project != null){
            throw new ApiException("project exists");
        }
        Map<String, String> body = new HashMap<>();
        body.put(DSConstants.PROJECT_NAME, projectName);
        body.put(DSConstants.DESCRIPTION, desc);
        body.put(DSConstants.USER_NAME, apiClient.getConfig().getUserName());
        Result result = apiClient.post(DSConstants.PROJECT_SERVICE_PATH, body, MediaTypeConstants.MEDIA_TYPE_FORM, Result.class);
        if (result.isFailed()) {
            throw new ApiException(result.getMsg());
        }

        return JsonUtils.toBean(result.getData(), Project.class);
    }

    @Override
    public void deleteProject(String projectName) {
        if (projectName == null) {
            throw new ApiException("project name is null");
        }

        Project project = this.getProject(projectName);

        Result result = apiClient.delete(DSConstants.PROJECT_UPDATE_DELETE_PATH, null, null, Result.class, project.getCode());
        if (result.isFailed()) {
            throw new ApiException(result.getMsg());
        }
    }

    @Override
    public boolean updateProject(String oldProjectName, String newProjectName, String newDesc) {
        if (oldProjectName == null || newProjectName == null) {
            throw new ApiException("project name is null");
        }
        Project project = this.getProject(oldProjectName);
        Map<String, String> body = new HashMap<>();
        body.put(DSConstants.PROJECT_NAME, newProjectName);
        body.put(DSConstants.DESCRIPTION, newDesc);
        body.put(DSConstants.USER_NAME, apiClient.getConfig().getUserName());
        Result result = apiClient.put(DSConstants.PROJECT_UPDATE_DELETE_PATH, body, MediaTypeConstants.MEDIA_TYPE_FORM, Result.class, project.getCode());
        if (result.isFailed()) {
            throw new ApiException(result.getMsg());
        }
        return false;
    }

    @Override
    public Project getProject(String projectName) {
        if (projectName == null) {
            throw new ApiException("project name is null");
        }
        Result result = apiClient.get(DSConstants.PROJECT_QUERY_PATH, Result.class, 10, 1, projectName);
        if (result.isFailed()) {
            throw new ApiException(result.getMsg());
        }
        PageInfo pageInfo = JsonUtils.toBean(result.getData(), PageInfo.class);

        String content = JsonUtils.converString(pageInfo.getTotalList());
        List<Project> projects = JsonUtils.toList(content, new TypeReference<List<Project>>() {
        });
        if (projects == null || projects.isEmpty()) {
            return null;
        }
        return projects.get(0);
    }

    @Override
    public ServiceType getServiceType() {
        return ServiceType.PROJECT;
    }
}
